﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;

namespace TMS
{
    public class ModuloXMLManager: XMLBaseManager
    {
        private static ModuloXMLManager _instancia;

        public static ModuloXMLManager getInstancia()
        {
            if (_instancia == null)
            {
                _instancia = new ModuloXMLManager();
            }
            return _instancia;
        }

        private ModuloXMLManager()
        {
            nombreRoot = "Modulos";
            nombreArchivo = nombreRoot + ".xml";
        }

        public void addModulo(Modulo pModulo)
        {
            XDocument xDoc = loadDoc(); //Carga el documento.
            XElement modulos = xDoc.Root; //Obtiene la raiz del documento XML.
            XElement modulo = new XElement("Modulo"); //Genera un nuevo elemento.
            modulo.SetAttributeValue("Id", "" + pModulo.Id); //Agrega Id como atributo.
            modulo.SetElementValue("Nombre", pModulo.Nombre); //Agrega el nombre del modulo.
            modulo.SetElementValue("Tipo", pModulo.Tipo); //Agrega el tipo del modulo.
            modulo.SetElementValue("Descripcion", pModulo.Descripcion); //Agrega la descripcion del modulo.
            modulo.SetElementValue("IdAplicacion", "" + pModulo.Aplicacion.Id); //Agrega el nombre de la aplicacion a la que pertenece.
            modulo.SetElementValue("IdDeveloper", "" + pModulo.Developer.NroUsuario); //Agrega el Id del desarrollador.
            modulos.Add(modulo); //Agrega el elemento definido antes a la raiz del documento.
            saveDoc(xDoc); //Guarda el documento.
        }
        public void updateModulo(Modulo pModulo)
        {
            XDocument xDoc = loadDoc(); //Carga el documento.
            XElement mod = xDoc.Root.Elements().Single(mo => (long)mo.Attribute("Id") == pModulo.Id);
            mod.SetElementValue("Nombre", pModulo.Nombre);
            mod.SetElementValue("Tipo", pModulo.Tipo);
            mod.SetElementValue("Descripcion", pModulo.Descripcion);
            mod.SetElementValue("IdAplicacion", "" + pModulo.Aplicacion.Id);
            mod.SetElementValue("IdDeveloper", "" + pModulo.Developer.NroUsuario);
            saveDoc(xDoc);
        }
        public void removeModulo(long pModId)
        {
            /*
             * Primero elimina los errores relacionados con el Modulo cuyo Id se recibe como parametro.
             * Luego se elimina dicho modulo.
             */ 
            ErrorXMLManager.getInstancia().removeErrorsByModId(pModId);
            this.removeById(pModId);
        }
        public Modulo getModuloByName(string pNom)
        {
            /*
             * devuelve un modulo correspondiente a un nombre dado.
             */ 
            Modulo m = new Modulo();
            XDocument xDoc = loadDoc();
            try
            {
                XElement mod = xDoc.Root.Elements().Single(mo => (string)mo.Element("Nombre") == pNom);
                m.Id = long.Parse(mod.Attribute("Id").Value);
                m.Tipo = mod.Element("Tipo").Value;
                m.Nombre = pNom;
                m.Descripcion = "" + mod.Element("Descripcion");
            }
            catch (InvalidOperationException)
            {
                m = null;
            }
            return m;
        }
        public Modulo getModuloById(long pId)
        {
            /* 
             * Devuelve un modulo correspondiente a un Id dado.
             */ 
            Modulo m = new Modulo();
            XDocument xDoc = loadDoc();
            try
            {
                XElement mod = xDoc.Root.Elements().Single(mo => (long)mo.Attribute("Id") == pId);
                m.Id = long.Parse(mod.Attribute("Id").Value);
                m.Tipo = mod.Element("Tipo").Value;
                m.Nombre = mod.Element("Nombre").Value;
                m.Descripcion = "" + mod.Element("Descripcion").Value;
                m.Aplicacion = AplicacionXMLManager.getInstancia().getAplicacionById(long.Parse(mod.Element("IdAplicacion").Value));
                m.Developer = DeveloperXMLManager.getInstancia().getDeveloperById(long.Parse(mod.Element("IdDeveloper").Value));
            }
            catch (InvalidOperationException)
            {
                m = null;
            }
            return m;
        }
        public List<Modulo> getModulosByApp(long appId)
        {
            List<Modulo> lstMods = new List<Modulo>();
            XDocument xDoc = loadDoc();
            foreach (XElement xe in xDoc.Root.Elements())
            {
                if (long.Parse(xe.Element("IdAplicacion").Value) == appId)
                {
                    Modulo unM = new Modulo();
                    unM.Id = long.Parse(xe.Attribute("Id").Value);
                    unM.Nombre = xe.Element("Nombre").Value;
                    unM.Tipo = xe.Element("Tipo").Value;
                    unM.Descripcion = xe.Element("Descripcion").Value;
                    unM.Aplicacion = AplicacionXMLManager.getInstancia().getAplicacionById(long.Parse(xe.Element("IdAplicacion").Value));
                    unM.Developer = DeveloperXMLManager.getInstancia().getDeveloperById(long.Parse(xe.Element("IdDeveloper").Value));
                    lstMods.Add(unM);
                }
            }
            return lstMods;
        }
        public void removeModsByIdApp(long pIdApp)
        {
            /*
             * Realiza iteraciones dentro de una lista de modulos relacionados a la aplicacion cuyo Id se suministra como parametro,
             * llamando la funcion de eliminacion de modulos en cada una de ellas y asignandole el Id de turno como parametro.
             */ 
            foreach (Modulo m in this.getModulosByApp(pIdApp))
            {
                this.removeModulo(m.Id);
            }
        }
        public bool existeModulo(string pNombre)
        {
            /*
             * Comprueba que no exista un Modulo registrado con ese nombre.
             */
            bool existe = false;
            XDocument xDoc = loadDoc(); //Carga el documento.
            try
            {
                XElement xEl = xDoc.Root.Elements().Single(a => (string)a.Element("Nombre") == pNombre);
                if (xEl != null)
                {
                    existe = true;
                }
            }
            catch (InvalidOperationException)
            {
                existe = false;
            }
            return existe;
        }
        
    }

}